<script setup>
import { ref, reactive, onMounted } from 'vue'
import _axios from "/src/utils/myAxios.js"
import { ElMessage, ElMessageBox } from 'element-plus'
import { handleTree } from '@/store/menuTree.js'
import { icons } from '@/store/icons.ts'


//搜索选项
let searchMenu = ref({
    menuName: undefined,
    status: undefined
})

let menu = ref([])
let menuOptions = ref([])
let defaultProps = ref({
    children: 'children',
    label: 'menuName'
})
//表单
let form = ref({
    id: undefined,
    menuName: undefined,
    parentId: 0,
    orderNum: undefined,
    path: undefined,
    component: undefined,
    menuType: 'M',
    visible: 0,
    status: 0,
    icon: undefined,
    permission: undefined,
})

//重置表单
function resetForm() {
    form.value = {
        id: undefined,
        menuName: undefined,
        parentId: 0,
        orderNum: undefined,
        path: undefined,
        component: undefined,
        menuType: 'M',
        visible: 0,
        status: 0,
        icon: undefined,
        permission: undefined,
    }
}

let formRule = reactive({ //菜单表单规则
    menuName: [
        { required: true, message: '菜单名称不能为空', trigger: 'blur' },
        { min: 1, max: 30, message: '长度在 1 到 30 个字符', trigger: 'blur' }
    ],
    orderNum: [
        { required: true, message: '显示排序不能为空', trigger: 'blur' },
    ],
    path: [
        { required: true, message: '路由地址不能为空', trigger: 'blur' },
        { min: 1, max: 30, message: '长度在 1 到 30 个字符', trigger: 'blur' }
    ]
})
let formRef = ref()

//弹框标题和是否可见
let dialog = ref({
    title: "",
    visible: false,
})

//获取菜单列表
async function getMenu() {
    let res = await _axios.get('/api/menu/list', {
        params: {
            menuName: searchMenu.value.menuName,
            status: searchMenu.value.status
        }
    })
    if (res.data.code == 200) {
        menu.value = handleTree(res.data.data)
    } else {
        ElMessage({
            showClose: true,
            message: res.data.message,
            type: 'error',
            appendTo: "#app",
        })
    }
}
onMounted(() => {
    getMenu()
})

//打开新增菜单对话框
function handleAdd(row) {
    resetForm()
    getTreeselect()
    if (row != null && row.id) {
        form.value.parentId = row.id
    } else {
        form.value.parentId = 0
    }
    dialog.value.visible = true
    dialog.value.title = '添加菜单'
}

/** 查询菜单下拉树结构 */
async function getTreeselect() {
    let resp = await _axios.get('/api/menu/list')
    if (resp.data.code === 200) {
        menuOptions.value = []
        const menu = { id: 0, menuName: '主类目', children: [] }
        menu.children = handleTree(resp.data.data, 'id')
        menuOptions.value.push(menu)
    }
}

//添加和修改
function submitForm() {
    formRef.value.validate(async valid => {
        if (valid) {
            if (form.value.id === undefined) {
                let resp = await _axios.post('/api/menu/addMenu', form.value)
                if (resp.data.code === 200) {
                    dialog.value.visible = false
                    getMenu()
                    ElMessage({
                        showClose: true,
                        message: "添加菜单成功",
                        type: 'success',
                        appendTo: "#app"
                    })
                } else {
                    ElMessage({
                        showClose: true,
                        message: resp.data.message,
                        type: 'error',
                        appendTo: "#app"
                    })
                }
            } else {
                let resp = await _axios.put('/api/menu/updateMenu', form.value)
                if (resp.data.code === 200) {
                    dialog.value.visible = false
                    getMenu()
                    ElMessage({
                        showClose: true,
                        message: "修改菜单成功",
                        type: 'success',
                        appendTo: "#app"
                    })
                } else {
                    ElMessage({
                        showClose: true,
                        message: resp.data.message,
                        type: 'error',
                        appendTo: "#app"
                    })
                }
            }
        } else {
            ElMessage({
                showClose: true,
                message: '请按规则填写',
                type: 'warning',
                appendTo: "#app"
            })
        }
    })
}

//取消
function cancel() {
    dialog.value.visible = false
}

//修改某个菜单
async function handleUpdate(id) {
    resetForm()
    getTreeselect()
    let resp = await _axios.get(`/api/menu/getMenuById/${id}`)
    if (resp.data.code === 200) {
        form.value = resp.data.data
        dialog.value.title = "修改菜单"
        dialog.value.visible = true
    } else {
        ElMessage({
            showClose: true,
            message: resp.data.message,
            type: 'error',
            appendTo: "#app"
        })
    }
}

function handleDelete(row) {
    ElMessageBox.confirm(
        '确定删除名为' + row.menuName + '的菜单？',
        '系统提示',
        {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
        }
    ).then(async () => {
        let resp = await _axios.delete(`/api/menu/deleteMenu/${row.id}`)
        return resp
    })
        .then((resp) => {
            if (resp.data.code === 200) {
                ElMessage({
                    showClose: true,
                    message: "删除成功",
                    type: 'success',
                    appendTo: "#app",
                })
                getMenu()
            } else {
                ElMessage({
                    showClose: true,
                    message: resp.data.message,
                    type: 'warning',
                    appendTo: "#app",
                })
            }
        })
}

function exportMenu() {
    ElMessageBox.confirm(
        '确认要导出所有角色数据吗？',
        '系统提示',
        {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
        }
    ).then(async () => {
        let res = await _axios.get('/api/menu/export', {
            responseType: 'blob'
        })
        if (!res.data) {
            return
        }
        var blob = new Blob([res.data])
        const contentDisposition = res.headers['content-disposition']
        var fileName = 'test.xlsx'
        if (contentDisposition) {
            fileName = window.decodeURI(res.headers['content-disposition'].split('=')[1], 'UTF-8')
        }
        var url = window.URL.createObjectURL(blob)
        var aLink = document.createElement('a')
        aLink.style.display = 'none'
        aLink.href = url
        aLink.setAttribute('download', fileName)
        document.body.appendChild(aLink)
        aLink.click()
        document.body.removeChild(aLink) // 下载完成移除元素
        window.URL.revokeObjectURL(url) // 释放掉blob对象
        return res
    })
        .then(() => {
            ElMessage({
                showClose: true,
                message: "数据导出成功",
                type: 'success',
                appendTo: "#app",
            })
            getMenu()
        })
}
</script>

<template>
    <div class="backMain">
        <el-form>
            <div class=" backMain-search">
                <el-form-item label="菜单名称">
                    <el-input v-model="searchMenu.menuName" placeholder="请输入菜单名称" />
                </el-form-item>
                <el-form-item label="菜单状态">
                    <el-select v-model="searchMenu.status" placeholder="请选择菜单状态">
                        <el-option label="正常" value=0 />
                        <el-option label="停用" value=1 />
                    </el-select>
                </el-form-item>
                <el-button type="primary" style="margin-left: 15px;" @click="getMenu()">搜索</el-button>
            </div>
            <div class="addAndDel">
                <el-button type="primary" plain size="small" @click="handleAdd">
                    <iEpPlus style="width: 16px;" />&nbsp;
                    新增
                </el-button>
                <el-button type="danger" plain size="small" @click="exportMenu()">
                    <iEpDownload style="width: 16px;"/>&nbsp;
                    导出
                </el-button>
            </div>
            <div class="user-content">
                <el-table :data="menu" row-key="id" :cell-style="{ backgroundColor: 'var(--el-page-bg-color)' }"
                    style="width: 100%;margin-top: 10px;"
                    :tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
                    <el-table-column prop="menuName" label="菜单名称" :show-overflow-tooltip="true" />
                    <el-table-column prop="icon" label="图标" align="center" width="100">
                        <template #default="scope">
                            <el-icon>
                                <component :is="scope.row.icon" />
                            </el-icon>
                        </template>
                    </el-table-column>
                    <el-table-column prop="orderNum" label="排序" />
                    <el-table-column prop="permission" label="权限标识" :show-overflow-tooltip="true" />
                    <el-table-column prop="component" label="组件路径" :show-overflow-tooltip="true" />
                    <el-table-column prop="status" label="状态">
                        <template #default="scope">
                            <el-tag v-if="scope.row.status === 0" type="success">正常</el-tag>
                            <el-tag v-if="scope.row.status === 1" type="danger">停用</el-tag>
                        </template>
                    </el-table-column>
                    <el-table-column prop="createTime" label="创建时间" align="center" />
                    <el-table-column label="操作" align="center" style="display: flex;">
                        <template #default="scope">
                            <el-button size="small" text style="color: #409EFF;margin: 0;"
                                @click="handleUpdate(scope.row.id)">修改</el-button>
                            <el-button size="small" text style="color: #409EFF;margin: 0;"
                                @click="handleAdd(scope.row)">新增</el-button>
                            <el-button size="small" text style="color: #409EFF;margin: 0;"
                                @click="handleDelete(scope.row)">删除</el-button>
                        </template>
                    </el-table-column>
                </el-table>
            </div>
        </el-form>
        <!-- 添加或修改菜单对话框 -->
        <el-dialog :title="dialog.title" v-model="dialog.visible" width="700px" append-to-body
            style="background-color: #fff;font-weight: 600;">
            <el-form ref="formRef" :model="form" :rules="formRule" label-width="100px">
                <el-form-item label="上级菜单">
                    <el-tree-select size="large" v-model="form.parentId" :data="menuOptions"
                        :render-after-expand="false" check-strictly node-key="id" placeholder="选择上级菜单"
                        :props="defaultProps" />
                </el-form-item>
                <el-form-item label="菜单类型" prop="menuType" size="large">
                    <el-radio-group v-model="form.menuType">
                        <el-radio value="M">目录</el-radio>
                        <el-radio value="C">菜单</el-radio>
                        <el-radio value="A">按钮</el-radio>
                    </el-radio-group>
                </el-form-item>
                <el-form-item v-if="form.menuType != 'F'" label="菜单图标" size="large">
                    <!-- <IconSelect ref="iconSelect" @selected="selected" /> -->
                    <el-select v-model="form.icon" placeholder="图标" clearable style="width: 240px">
                        <el-option v-for="(icon, index) in icons" :key="index" :value="icon"
                            style="align-items: center; display: flex;">
                            <span>
                                <component :is="icon" style="width: 16px;" />{{ icon }}
                            </span>
                        </el-option>
                    </el-select>
                </el-form-item>
                <div style="display: flex;">
                    <el-form-item label="菜单名称" prop="menuName" size="large">
                        <el-input v-model="form.menuName" placeholder="请输入菜单名称" />
                    </el-form-item>
                    <el-form-item label="显示排序" prop="orderNum" size="large">
                        <el-input-number v-model="form.orderNum" controls-position="right" :min="1" />
                    </el-form-item>
                </div>
                <el-form-item v-if="form.menuType != 'A'" prop="path">
                    <template #label>
                        <el-tooltip content="访问的路由地址，如：`user`" placement="top">
                            <iEpQuestionFilled style="width: 18px;margin: auto;" />
                        </el-tooltip>
                        路由地址
                    </template>
                    <el-input v-model="form.path" placeholder="请输入路由地址" size="large" />
                </el-form-item>
                <div style="display: flex;">
                    <el-form-item prop="component" style="display: flex;align-items: center;"
                        v-if="form.menuType == 'C'">
                        <template #label>
                            <el-tooltip content="访问的组件路径，如：`user`，默认在`views/backstage`目录下" placement="top">
                                <iEpQuestionFilled style="width: 18px;margin: auto;" />
                            </el-tooltip>
                            组件路径
                        </template>
                        <el-input v-model="form.component" placeholder="请输入组件路径" size="large" />
                    </el-form-item>
                    <el-form-item v-if="form.menuType != 'M'" style="display: flex;align-items: center;">
                        <template #label>
                            <el-tooltip content="控制器中定义的权限字符，如：@PreAuthorize(`@ss.hasPermi('system:user:list')`)"
                                placement="top">
                                <iEpQuestionFilled style="width: 18px;margin: auto;" />
                            </el-tooltip>
                            权限字符
                        </template>
                        <el-input v-model="form.permission" placeholder="请输入权限标识" maxlength="100" size="large" />
                    </el-form-item>
                </div>
                <div style="display: flex;">
                    <el-form-item v-if="form.menuType != 'A'"
                        style="display: flex;align-items: center;margin-right: 35px;">
                        <template #label>
                            <el-tooltip content="选择隐藏则路由将不会出现在侧边栏，但仍然可以访问" placement="top">
                                <iEpQuestionFilled style="width: 18px;margin: auto;" />
                            </el-tooltip>
                            显示状态
                        </template>
                        <el-radio-group v-model="form.visible" size="large">
                            <el-radio :key="'0'" :value="0">显示</el-radio>
                            <el-radio :key="'1'" :value="1">隐藏</el-radio>
                        </el-radio-group>
                    </el-form-item>
                    <el-form-item v-if="form.menuType != 'A'" style="display: flex;align-items: center;">
                        <template #label>
                            <el-tooltip content="选择停用则路由将不会出现在侧边栏，也不能被访问" placement="top">
                                <iEpQuestionFilled style="width: 18px;margin: auto;" />
                            </el-tooltip>
                            菜单状态
                        </template>
                        <el-radio-group v-model="form.status" size="large">
                            <el-radio :key="'0'" :value="0">正常</el-radio>
                            <el-radio :key="'1'" :value="1">停用</el-radio>
                        </el-radio-group>
                    </el-form-item>
                </div>
            </el-form>
            <template #footer>
                <div class="dialog-footer">
                    <el-button @click="cancel">取消</el-button>
                    <el-button type="primary" @click="submitForm()">
                        确认
                    </el-button>
                </div>
            </template>
        </el-dialog>
    </div>
</template>

<style scoped></style>